//
// Created by hjie on 23-7-18.
//

#pragma once
extern "C"
{
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libavutil/timestamp.h>
#include <libavutil/threadmessage.h>
#include <libavcodec/packet.h>
#include <libavfilter/avfilter.h>
#include <libavutil/mem.h>
#include <libavutil/opt.h>
#include <libavfilter/buffersrc.h>
#include <libavfilter/buffersink.h>
#include <libswresample/swresample.h>
#include <libswscale/swscale.h>

};
#include <cstring>
#include <string>
#include <vector>
#include <functional>
#include <iostream>
#include <memory>
#include "message_queue.h"

void PrintLogInfo(const std::string & file, const std::string & function, int line, int error_code);
void PrintLogInfo(const std::string & file, const std::string & function, int line, const std::string & message);

#define PrintLog(error_code) PrintLogInfo(__FILE__, __FUNCTION__, __LINE__, error_code)
#define PrintLogMsg(msg)     PrintLogInfo(__FILE__, __FUNCTION__, __LINE__, msg)


int DecoderAudioOrVideoData(AVCodecContext * codec_context, AVPacket * packet, std::vector<AVFrame*> & frame_vec, bool is_transfer=true);

int EncoderAudioOrVideoData(AVCodecContext * codec_context, AVFrame * frame, std::vector<AVPacket*> & packet_vec);

void ReleaseAVFormatCtx(AVFormatContext ** format_context);

std::string GetErrorMessage(int error_code);


int DecoderPacketData(AVCodecContext * codec_context, AVPacket * packet, FrameMessageQueue & queue);
int DecoderPacketDataAndTransfer(AVCodecContext * codec_context, AVPacket * packet, FrameMessageQueue & queue);
int EncoderFrameData(AVCodecContext * codec_context, AVFrame  * frame,  PacketMessageQueue & queue);

int ProcessPacketMessageQueue(AVCodecContext * codec_context, PacketMessageQueue & packet_queue, FrameMessageQueue & frame_queue);
int ProcessFrameMessageQueue(AVCodecContext * codec_context, FrameMessageQueue & frame_queue, PacketMessageQueue & packet_queue);

int ProcessNullptrPacket(AVCodecContext * codec_context, FrameMessageQueue  & frame_queue);
int ProcessNullPtrPacketAndTransfer(AVCodecContext * codec_context, FrameMessageQueue & frame_queue);

int ProcessNullptrFrame(AVCodecContext * codec_context,  FrameMessageQueue & frame_queue, PacketMessageQueue & packet_queue);

void ReadFrameToQueue(AVFormatContext * format_context, AVPacket * packet, PacketMessageQueue & packet_queue);




